package com.zx._09_架构.load_balance;

import com.zx.common.util.ThreadUtil;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import lombok.AllArgsConstructor;
import lombok.Data;

public class LB_FIFO_LIFO {

    private static final LinkedBlockingQueue<OO> FIFO = new LinkedBlockingQueue<>(10);
    private static final LinkedBlockingDeque<OO> LIFO = new LinkedBlockingDeque<>(10);

    private static final int c = 1;

    public static void main(String[] args) throws InterruptedException {
        System.out.println("FIFO");
        fifo();

        System.out.println("LIFO");
        lifo();

        System.out.println("Done");
    }

    public static void fifo() throws InterruptedException {
        FIFO.put(new OO(1));
        FIFO.put(new OO(2));
        FIFO.put(new OO(3));

        CountDownLatch countDownLatch = new CountDownLatch(c);
        for (int i = 0; i < c; i++) {
            new Thread(() -> {
                for (int j = 0; j < 10; j++) {
                    try {
                        OO oo = FIFO.take();
                        ThreadUtil.sleepMill(oo.getId() * 100);
                        System.out.println(oo);
                        FIFO.put(oo);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                countDownLatch.countDown();
            }).start();
        }
        countDownLatch.await();
    }

    public static void lifo() throws InterruptedException {
        // 压入栈
        LIFO.put(new OO(1));
        LIFO.put(new OO(2));
        LIFO.put(new OO(3));

        CountDownLatch countDownLatch = new CountDownLatch(c);
        for (int i = 0; i < c; i++) {
            new Thread(() -> {
                for (int j = 0; j < 10; j++) {
                    try {
                        // 弹出栈
                        OO oo = LIFO.takeLast();
                        ThreadUtil.sleepMill(oo.getId() * 100);
                        System.out.println(oo);
                        LIFO.put(oo);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
                countDownLatch.countDown();
            }).start();
        }
        countDownLatch.await();
    }


    @Data
    @AllArgsConstructor
    private static class OO {

        private int id;
    }
}
